package com.czc.mvc.config;


import com.czc.constant.CrowdConstant;

import com.czc.exception.LoginAcctAlreadyInUseException;
import com.czc.exception.LoginAcctAlreadyInUseForUpdateException;
import com.czc.exception.LoginFailedException;
import com.czc.util.CrowdUtil;
import com.czc.util.ResultEntity;
import com.google.gson.Gson;

import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

//@ControllerAdvice表示当前类是一个基于注解的异常处理类
@ControllerAdvice
public class CrowdExceptionResolver {

    //更新用户名相同的异常处理
    @ExceptionHandler(value = LoginAcctAlreadyInUseForUpdateException.class)
    public ModelAndView resolveLoginAcctAlreadyInUseForUpdateException(
            LoginAcctAlreadyInUseForUpdateException exception,
            HttpServletRequest request,
            HttpServletResponse response) throws IOException {

        String viewName="system-error";

        return commonResoolve(viewName,exception,request,response);
    }

    //新增或更新 登入名重复的异常
    @ExceptionHandler(value = LoginAcctAlreadyInUseException.class)
    public ModelAndView resolveLoginAcctAlreadyInUseException(LoginAcctAlreadyInUseException exception,
                                                        HttpServletRequest request,
                                                        HttpServletResponse response) throws IOException {

        String viewName="admin-add";

        return commonResoolve(viewName,exception,request,response);
    }

    @ExceptionHandler(value = Exception.class)
    public ModelAndView resolveException(Exception exception,
                                                    HttpServletRequest request,
                                                    HttpServletResponse response) throws IOException {

        String viewName="system-error";

        return commonResoolve(viewName,exception,request,response);
    }


    @ExceptionHandler(value = LoginFailedException.class)
    public ModelAndView resolveLoginFailedException(LoginFailedException exception,
                                                    HttpServletRequest request,
                                                    HttpServletResponse response) throws IOException {

        String viewName="admin-login";

        return commonResoolve(viewName,exception,request,response);
    }

    //@ExceptionHandler将一个具体的异常类型和一个方法联系起来
    @ExceptionHandler(value = NullPointerException.class)
    public ModelAndView resolveNullPointerException(NullPointerException exception,
                                                    HttpServletRequest request,
                                                    HttpServletResponse response) throws IOException {

        String viewName="system-error";

        return commonResoolve(viewName,exception,request,response);
    }


    @ExceptionHandler(value = ArithmeticException.class)
    public ModelAndView resolveMathException(ArithmeticException exception,
                                             HttpServletRequest request,
                                             HttpServletResponse response) throws IOException {

        String viewName="system-error";

        return commonResoolve(viewName,exception,request,response);
    }


    private ModelAndView commonResoolve(String viewName,
                                        Exception exception,
                                        HttpServletRequest request,
                                        HttpServletResponse response) throws IOException {
        //1.判断当前请求类型
        boolean type = CrowdUtil.judgeRequestType(request);
        //2.如果是ajax请求
        if (type) {

            //3.创建ResultEnity对象
            ResultEntity<Object> resultEntity = ResultEntity.failed(exception.getMessage());

            //4.创建Gson对象转换json
            Gson gson = new Gson();
            String s = gson.toJson(resultEntity);

            //5.响应给浏览器
            response.getWriter().write(s);

            //6.由于上面已经通过原生response对象返回了响应，所以不提供ModelAndView对象
            return null;

        }

        ModelAndView modelAndView = new ModelAndView();
        //将Exception对象存入模型  使用常量避免出错
        modelAndView.addObject(CrowdConstant.ATTR_NAME_EXCEPTION, exception);

        //设置对应视图名称
        modelAndView.setViewName(viewName);

        return modelAndView;
    }
}
